package cn.lingyangwl.framework.ip2region.factory;

import cn.lingyangwl.framework.core.constant.LyCoreConstants;
import cn.lingyangwl.framework.core.http.HttpRequestServletManager;
import cn.lingyangwl.framework.core.utils.IpUtils;
import cn.lingyangwl.framework.ip2region.constants.IpOfflineType;
import cn.lingyangwl.framework.ip2region.handler.Ip2RegionHandler;
import cn.lingyangwl.framework.ip2region.handler.Ip2RegionOfflineHandler;
import cn.lingyangwl.framework.ip2region.config.properties.LyIpProperties;
import org.lionsoul.ip2region.xdb.Searcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * <a href="https://gitee.com/lionsoul/ip2region">ip2region官网</a>
 *
 * @author shenguangyang
 */
@Component
@ConditionalOnClass(Searcher.class)
@ConditionalOnProperty(prefix = LyCoreConstants.PROPERTIES_PRE + "ip2region", value = "offline.type", havingValue = IpOfflineType.IP2REGION)
public class Ip2RegionOffline implements Ip2RegionOfflineFactory {
    private static final Logger log = LoggerFactory.getLogger(Ip2RegionOffline.class);
    @Resource
    private LyIpProperties lyIpProperties;
    private byte[] vectorIndex;

    @PostConstruct
    public void init() {
        // 从 dbPath 中预先加载 VectorIndex 缓存，并且把这个得到的数据作为全局变量，后续反复使用。
        String databasePath = lyIpProperties.getOffline().getDatabasePath();
        try {
            vectorIndex = Searcher.loadVectorIndexFromFile(databasePath);
        } catch (Exception e) {
            log.error("failed to load vector index from [{}]: ", databasePath, e);

        }
    }

    @Override
    public Ip2RegionOfflineHandler create(HttpServletRequest request) {
        String ip = IpUtils.getRequestIp(new HttpRequestServletManager(request));
        String databasePath = lyIpProperties.getOffline().getDatabasePath();
        return new Ip2RegionHandler(ip, vectorIndex, databasePath);
    }

    @Override
    public Ip2RegionOfflineHandler create(String ip) {
        String databasePath = lyIpProperties.getOffline().getDatabasePath();
        return new Ip2RegionHandler(ip, vectorIndex, databasePath);
    }
}
